package com.stox.ui.javafx.charting.widget;

import javafx.geometry.Insets;
import javafx.geometry.Side;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.VBox;

import org.controlsfx.control.RangeSlider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.stox.dto.preference.PreferenceFactory;
import com.stox.ui.javafx.charting.event.handler.InformationAxisMouseMovedEventHandler;
import com.stox.ui.javafx.charting.event.listener.RangeSliderValueChangeListener;
import com.stox.ui.javafx.charting.model.ChartingPreference;
import com.stox.ui.javafx.charting.model.enumeration.ChartType;
import com.stox.ui.javafx.charting.model.plot.AbstractPrimaryPlot;
import com.stox.ui.javafx.charting.view.ChartingView;
import com.stox.ui.javafx.charting.widget.axis.AbstractHorizontalAxis;
import com.stox.ui.javafx.charting.widget.axis.DateAxis;
import com.stox.ui.javafx.charting.widget.axis.InformationAxis;

@Component("primaryChart")
@SuppressWarnings("rawtypes")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrimaryChart<T extends AbstractPrimaryPlot> extends Chart<T> {
	
	private boolean semilog;

	private boolean equivolume;
	
	private RangeSlider rangeSlider = new RangeSlider(0,1000,0,1000);
	
	private AbstractHorizontalAxis topHorizontalAxis;
	
	private AbstractHorizontalAxis bottomHorizontalAxis;
	
	public PrimaryChart(ChartingView chartingView) {
		super(chartingView);
		getStyleClass().add("primary-chart");
		rangeSlider.setBackground(new Background(new BackgroundFill(PreferenceFactory.get(ChartingPreference.class).getBackgroundColor(),new CornerRadii(0), new Insets(0))));
		int defaultBars = chartingView.getDefaultBars();
		int autoFetchSize = chartingView.getAutoFetchSize();
		rangeSlider.setMin(-1*(autoFetchSize)*1000/defaultBars);
	}
	
	@Autowired
	public void setApplicationContext(ApplicationContext applicationContext){
		super.setApplicationContext(applicationContext);
		
		topHorizontalAxis = applicationContext.getBean(InformationAxis.class);
		topHorizontalAxis.setChart(this);
		topHorizontalAxis.setSide(Side.TOP);
		
		bottomHorizontalAxis = applicationContext.getBean(DateAxis.class);
		bottomHorizontalAxis.setChart(this);
		bottomHorizontalAxis.setSide(Side.BOTTOM);
		setBottom(new VBox(bottomHorizontalAxis, rangeSlider));
		
		RangeSliderValueChangeListener rangeSliderValueChangeListener = (RangeSliderValueChangeListener)applicationContext.getBean("rangeSliderValueChangeListener", this);
		rangeSlider.lowValueProperty().addListener(rangeSliderValueChangeListener);
		rangeSlider.highValueProperty().addListener(rangeSliderValueChangeListener);
		
		final InformationAxisMouseMovedEventHandler informationAxisMouseMovedEventHandler = applicationContext.getBean(InformationAxisMouseMovedEventHandler.class);
		getCanvas().addEventHandler(MouseEvent.MOUSE_MOVED, informationAxisMouseMovedEventHandler);
	}
	
	@Override
	public void update() {
		if(getFrontPlot() ==  null ) return;
		
		super.update();
	}
	
	@Override
	public void paint() {
		if(null != topHorizontalAxis)	topHorizontalAxis.paint();
		if(null != bottomHorizontalAxis) 	bottomHorizontalAxis.paint();
		super.paint();
	}
	
	public RangeSlider getRangeSlider() {
		return rangeSlider;
	}
	
	@Override
	public void setFrontPlot(T frontPlot) {
		//TODO take ChartType from current chart type instead of hardcoding
		frontPlot.setChartType(ChartType.HLC);
		super.setFrontPlot(frontPlot);
		getChartingView().setTitle(frontPlot.getModel().getName().trim()+" - "+frontPlot.getModel().getId());
		frontPlot.setVolumeData();
		//getChartingView().setBuzy(false);
	}
	
	public AbstractHorizontalAxis getTopHorizontalAxis() {
		return topHorizontalAxis;
	}
	
	@Override
	public T getFrontPlot() {
		return super.getFrontPlot();
	}
	
	public boolean isSemilog() {
		return semilog;
	}

	public void setSemilog(boolean semilog) {
		this.semilog = semilog;
	}
	
	public boolean isEquivolume() {
		return equivolume;
	}

	public void setEquivolume(boolean equivolume) {
		this.equivolume = equivolume;
	}


}
